use codegraph_core::Result;
use codegraph_storage::{
    distributed::{DistributedStorage, DistributedConfig, ConsistencyLevel},
    redis::RedisConfig,
};

#[tokio::main]
async fn main() -> Result<()> {
    println!("🚀 CodeGraph-RT Distributed Storage Demo");
    println!("=========================================\n");

    // 1. Configure distributed storage with multiple Redis shards
    println!("1. Setting up distributed storage configuration...");
    let config = DistributedConfig {
        shard_nodes: vec![
            RedisConfig {
                url: "redis://localhost:6379/0".to_string(),
                pool_size: 10,
                key_prefix: "codegraph:shard1:".to_string(),
                ttl: Some(3600), // 1 hour
                cluster_mode: false,
                cluster_nodes: vec![],
                connection_timeout_ms: 5000,
                command_timeout_ms: 3000,
            },
            RedisConfig {
                url: "redis://localhost:6379/1".to_string(),
                pool_size: 10,
                key_prefix: "codegraph:shard2:".to_string(),
                ttl: Some(3600),
                cluster_mode: false,
                cluster_nodes: vec![],
                connection_timeout_ms: 5000,
                command_timeout_ms: 3000,
            },
            RedisConfig {
                url: "redis://localhost:6379/2".to_string(),
                pool_size: 10,
                key_prefix: "codegraph:shard3:".to_string(),
                ttl: Some(3600),
                cluster_mode: false,
                cluster_nodes: vec![],
                connection_timeout_ms: 5000,
                command_timeout_ms: 3000,
            },
        ],
        replication_factor: 2,
        read_consistency: ConsistencyLevel::Majority,
        write_consistency: ConsistencyLevel::Majority,
        auto_failover: true,
        health_check_interval: 30,
    };
    println!("✅ Configured {} shards with replication factor {}", 
             config.shard_nodes.len(), config.replication_factor);

    // 2. Initialize distributed storage
    println!("\n2. Initializing distributed storage system...");
    match DistributedStorage::new(config).await {
        Ok(storage) => {
            println!("✅ Distributed storage initialized successfully");
            
            // 3. Perform health check
            println!("\n3. Performing health check on all shards...");
            match storage.health_check().await {
                Ok(health_status) => {
                    for (shard_id, is_healthy) in health_status {
                        let status = if is_healthy { "✅ Healthy" } else { "❌ Unhealthy" };
                        println!("   Shard {}: {}", shard_id, status);
                    }
                }
                Err(e) => {
                    println!("⚠️  Health check failed: {}", e);
                }
            }
            
            // 4. Get cluster statistics
            println!("\n4. Retrieving cluster statistics...");
            match storage.get_cluster_stats().await {
                Ok(stats) => {
                    println!("   📊 Cluster Statistics:");
                    println!("      Total shards: {}", stats.total_shards);
                    println!("      Healthy shards: {}", stats.healthy_shards);
                    println!("      Replication factor: {}", stats.replication_factor);
                    println!("      Consistency level: {:?}", stats.consistency_level);
                }
                Err(e) => {
                    println!("⚠️  Failed to get cluster stats: {}", e);
                }
            }
            
            // 5. Demonstrate data distribution
            println!("\n5. Demonstrating data distribution across shards...");
            let test_keys = vec![
                "user:1001",
                "user:1002", 
                "user:1003",
                "project:alpha",
                "project:beta",
                "project:gamma",
                "function:calculate",
                "function:validate",
                "class:DataProcessor",
                "class:ApiHandler",
            ];
            
            for key in &test_keys {
                match storage.get_shard_for_key(key).await {
                    Ok(shard_id) => {
                        println!("   📍 Key '{}' → Shard {}", key, shard_id);
                    }
                    Err(e) => {
                        println!("   ❌ Failed to determine shard for '{}': {}", key, e);
                    }
                }
            }
            
            println!("\n6. Testing distributed storage operations...");
            println!("   Note: Actual storage operations require Redis server running");
            println!("   To test with real Redis:");
            println!("   1. Start Redis server: redis-server");
            println!("   2. Run this demo again");
            
        }
        Err(e) => {
            println!("❌ Failed to initialize distributed storage: {}", e);
            println!("   This is expected if Redis server is not running");
            println!("   To run the full demo:");
            println!("   1. Install Redis: https://redis.io/download");
            println!("   2. Start Redis server: redis-server");
            println!("   3. Run this demo again");
        }
    }

    // 7. Show architectural benefits
    println!("\n7. 🏗️  Distributed Storage Architecture Benefits:");
    println!("   ✅ Horizontal Scalability - Add more Redis shards as needed");
    println!("   ✅ High Availability - Automatic failover between replicas");
    println!("   ✅ Consistent Hashing - Even data distribution across shards");
    println!("   ✅ Configurable Consistency - Choose between speed and consistency");
    println!("   ✅ Health Monitoring - Automatic shard health checking");
    println!("   ✅ Load Balancing - Distribute queries across healthy shards");

    println!("\n8. 🔧 Configuration Options:");
    println!("   • Replication Factor: Control data redundancy");
    println!("   • Consistency Levels: Any, Majority, All");
    println!("   • Auto Failover: Automatic recovery from shard failures");
    println!("   • Health Check Interval: Configurable monitoring frequency");
    println!("   • Connection Pooling: Efficient resource utilization");

    println!("\n🎉 Distributed Storage Demo Complete!");
    println!("The system is ready for production workloads with:");
    println!("   • Multi-shard data distribution");
    println!("   • Automatic replication and failover");
    println!("   • Configurable consistency guarantees");
    println!("   • Real-time health monitoring");

    Ok(())
}
